package com.flycms.modules.images.service.impl;

import com.flycms.common.utils.FileUtils;
import com.flycms.common.utils.ScaleImageUtils;
import com.flycms.common.utils.SnowFlakeUtils;
import com.flycms.common.utils.StrUtils;
import com.flycms.common.utils.file.FileUploadUtils;
import com.flycms.common.utils.security.Md5Utils;
import com.flycms.framework.config.properties.FlyMallProperties;
import com.flycms.modules.images.domain.Images;
import com.flycms.modules.images.domain.ImagesInfoMerge;
import com.flycms.modules.images.mapper.ImagesMapper;
import com.flycms.modules.images.service.IImagesService;
import com.flycms.modules.user.service.IUserService;
import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.*;
import java.net.HttpURLConnection;
import java.net.URL;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * Open source house, All rights reserved
 * 开发公司：28844.com<br/>
 * 版权：开源中国<br/>
 *
 * 图片管理服务
 *
 * @author sunkaifei
 *
 */
@Service
public class ImagesServiceImpl implements IImagesService {
	private Logger logger = Logger.getLogger(this.getClass());
    @Autowired
    private IUserService userService;

	@Autowired
	private ImagesMapper imagesMapper;

	// ///////////////////////////////
	// ///// 增加 ////////
	// ///////////////////////////////
	/**
	 * 保存内容中的图片本地化路径处理
	 *
	 * @param typeId
	 *         信息类型，0问题，1答案，2文章，3分享
	 * @param infoId
	 *         信息id
	 * @param userId
	 *         用户id
	 * @param content
	 *         需要分析处理并下载的内容
	 * @return
	 * @throws Exception
	 */
	public String replaceContent(Integer typeId,Long infoId,Long userId,String content) {
		Pattern pRemoteFileurl = Pattern.compile("<img.*?src=\"?(.*?)(\"|>|\\s+)");
		Matcher mRemoteFileurl = pRemoteFileurl.matcher(content);
		StringBuffer sb = new StringBuffer();
		String remoteFileurl = null;
		int nFileNum = 0;
		String imgpath = FileUploadUtils.getImgPath();
		StringBuffer imgBuffer = new StringBuffer();
		while (mRemoteFileurl.find()) {
			remoteFileurl = mRemoteFileurl.group(1);
			String extension = StrUtils.getImageUrlSuffix(remoteFileurl);
			extension = "." + extension;
			SimpleDateFormat df = new SimpleDateFormat("yyyyMMddHHmmss");
			String filename = Md5Utils.hash(infoId+df.format(new Date()) + nFileNum) + "_"+ nFileNum + extension;
			String reg = "(?!.*((97560.com)|(127.0.0.1)|(^/uploads/content/)|(/images/facebox/))).*$";
			String pathac ="";
			if (remoteFileurl.matches(reg)) {
				saveUrlAs(remoteFileurl, FlyMallProperties.getUploadPath() +imgpath + filename);
				pathac = "/uploads"+imgpath + filename;
				mRemoteFileurl.appendReplacement(sb, "<img src=\"" + pathac+"\" ");
				if (imgBuffer.toString().length() < 1) {
					imgBuffer.append(imgpath + filename);
				} else {
					imgBuffer.append(";").append(imgpath + filename);
				}
				nFileNum = nFileNum + 1;
			} else {
				if (getContentUrl(remoteFileurl)) {
					if(FileUtils.isFile(FlyMallProperties.getUploadPath() + "/" + StrUtils.getImageRootUrl(remoteFileurl))){  //判断文件是否存在，不存在则不执行
						FileUtils.moveFile(FlyMallProperties.getUploadPath() + "/" + StrUtils.getImageRootUrl(remoteFileurl),FlyMallProperties.getUploadPath() + imgpath + filename);//开始移动文件
					}
					pathac = imgpath + filename;
					mRemoteFileurl.appendReplacement(sb, "<img src=\"" + pathac+"\" ");
				}

				nFileNum = nFileNum + 1;
			}
			String pictureUrl= null;
			if (remoteFileurl.matches(reg)) {
				pictureUrl = "/uploads"+imgpath + filename;
			} else {
				pictureUrl =  remoteFileurl;
			}
			Images imaData=this.findImagesByImgurl(pictureUrl);
			try {
				if(imaData==null){
					File picture = new File(FlyMallProperties.getUploadPath() +imgpath + filename);
					FileInputStream fis = new FileInputStream(picture);
					BufferedImage sourceImg = ImageIO.read(fis);
					Images images = new Images();
					images.setId(SnowFlakeUtils.nextId());
					images.setImgUrl(pictureUrl);
					images.setFileSize(String.format("%.1f", picture.length() / 1024.0));
					images.setImgWidth(Integer.toString(sourceImg.getWidth()));
					images.setImgHeight(Integer.toString(sourceImg.getHeight()));
					images.setSort(nFileNum);
					images.setCreateTime(new Date());
					images.setInfoCount(1);
					int totalCount=imagesMapper.addImages(images);
					if(totalCount > 0){
						ImagesInfoMerge merge = new ImagesInfoMerge();
						merge.setId(SnowFlakeUtils.nextId());
						merge.setInfoType(typeId);
						merge.setInfoId(infoId);
						merge.setImgId(images.getId());
						merge.setUserId(userId);
						imagesMapper.addImagesInfoMerge(merge);
					}
					fis.close();
				}else{
					ImagesInfoMerge merge = new ImagesInfoMerge();
					merge.setId(SnowFlakeUtils.nextId());
					merge.setInfoType(typeId);
					merge.setInfoId(infoId);
					merge.setImgId(imaData.getId());
					merge.setUserId(userId);
					imagesMapper.addImagesInfoMerge(merge);
					imagesMapper.updateImagesCount(imaData.getId());
				}
			}catch(Exception e){
				logger.error("获取图片错误！");
			}
		}
		mRemoteFileurl.appendTail(sb);
		return sb.toString();
	}

	// ///////////////////////////////
	// ///// 刪除 ////////
	// ///////////////////////////////
	/**
	 * 按图片索引ID删除图片信息
	 *
	 * @param id
	 * @return
	 */
	public boolean deleteImagesById(Long id) {
		int totalCount = imagesMapper.deleteImagesById(id);
        return totalCount > 0 ? true : false;
	}

	/**
	 * 按图片信息id和图片指纹删除图片信息
     * @param tid
     *         信息id
	 * @param imgurl
     *         图片地址
	 * @return
	 */
	public boolean deleteImagesByTidAndImgurl(Long tid, String imgurl) {
		int totalCount = imagesMapper.deleteImagesByTidAndImgurl(tid,imgurl);
        return totalCount > 0 ? true : false;
	}

	/**
	 * 按信息分类和内容id删除图片信息
	 *
	 * @param channelid
	 *        信息分类id
	 * @param article_id
	 *        内容id
	 * @return
	 */
	public boolean deleteImagesByTid(Integer channelid,Long article_id) {
		List<Images> imglist=imagesMapper.getImagesListByTid(article_id);
		if(imglist.size()>0){//未做排除有其他内容内有本文中的图片
			for (Images list : imglist) {
				FileUtils.delFileA(FlyMallProperties.getUploadPath() + list.getImgUrl()); //删除内容中图片
			}
		}
		int totalCount = imagesMapper.deleteImagesByTid(channelid,article_id);
        return totalCount > 0 ? true : false;
	}

	/**
	 * 删除图片文件和图片数据
	 *
	 * @param tid
     *         信息id
	 * @param imgurl
     *         图片地址
	 * @return
	 */
	public boolean delImagesByDateAndFile(Long tid, String imgurl) {
		FileUtils.delFileA(FlyMallProperties.getUploadPath() + imgurl); //删除内容中图片
		int totalCount = imagesMapper.deleteImagesByTidAndImgurl(tid,imgurl);
        return totalCount > 0 ? true : false;
	}
	// ///////////////////////////////
	// ///// 修改 ////////
	// ///////////////////////////////



	// ///////////////////////////////
	// ///// 查询 ////////
	// ///////////////////////////////

	/**
	 * 按信息类型id和信息id查询第一个文章图片
	 *
	 * @param imgUrl
	 * @return
	 */
	public Images findImagesByImgurl(String imgUrl){
		return imagesMapper.findImagesByImgurl(imgUrl);
	}

    /**
     * 用信息id和图片地址查询该图片是否存在
     *
     * @param imgurl
     *         图片指纹
     * @return
     */
    public boolean checkImagesByTidAndImgurl(Long tid, String imgurl) {
        int totalCount = imagesMapper.checkImagesByTidAndImgurl(tid,imgurl);
        return totalCount > 0 ? true : false;
    }

	/**
	 * 查询图片路径是否存在
	 *
	 * @param imgUrl
	 *        图片地址
	 * @return
	 */
	public boolean checkImagesByImgurl(String imgUrl) {
		int totalCount = imagesMapper.checkImagesByImgurl(imgUrl);
        return totalCount > 0 ? true : false;
	}

	/**
	 * 按信息id查询所有关联图片的数量
	 *
	 * @param channelid
	 *        信息类别id
	 * @param img_width
	 *        图片宽度
	 * @param img_height
	 *        图片高度
	 * @return
	 */
	public int getImagesByTidListCount(Integer channelid, Integer img_width, Integer img_height){
		return imagesMapper.getImagesByTidListCount(channelid,img_width,img_height);
	}


	/**
	 * 缩放图片服务处理
	 *
	 * @param width
	 * @param height
	 * @param savePath
	 * @param targetURL
	 * @return
	 * @throws IOException
	 */
	public String thumbImages(Integer width, Integer height,String savePath, String targetURL) throws IOException {
		if(width>0 && height>0){
			ScaleImageUtils.forcedResize(width,height,savePath, new File(targetURL));
		}else{
			if(width>0){
				ScaleImageUtils.resize(width,savePath, new File(targetURL));
			}else if(height>0){
				ScaleImageUtils.resizeByHeight(height,savePath, new File(targetURL));
			}
		}
		return savePath;
	}

	/**
	 * 查询图片list内是否包含该图片路径
	 *
	 * @param name
	 * @param list
	 * @return
	 */
	public boolean listSearch(String name,List<Images> list){
		   for(int i=0; i < list.size(); i++){
		      if(name.equals(list.get(i).getImgUrl())){
		    	  return true;
		      }
		   }
		   return false;
	}



    public static void uploadFile(byte[] file, String filePath, String fileName) throws Exception {
        File targetFile = new File(filePath);
        if(!targetFile.exists()){
            targetFile.mkdirs();
        }
        FileOutputStream out = new FileOutputStream(filePath+fileName);
        out.write(file);
        out.flush();
        out.close();
    }

	/**
	 * @param fileUrl
	 *            文件来源地址
	 * @param savePath
	 *            文件保存地址
	 * @return
	 */
	public static boolean saveUrlAs(String fileUrl, String savePath) {
		try {
			URL url = new URL(fileUrl);
			HttpURLConnection connection = (HttpURLConnection) url.openConnection();
			DataInputStream in = new DataInputStream(connection.getInputStream());
			DataOutputStream out = new DataOutputStream(new FileOutputStream(savePath));
			byte[] buffer = new byte[4096];
			int count = 0;
			while ((count = in.read(buffer)) > 0) {
				out.write(buffer, 0, count);
			}
			out.close();
			in.close();
			connection.disconnect();
			return true;

		} catch (Exception e) {
			return false;
		}
	}


	/**
	 * 判断url是否是用户临时文件
	 *
	 * @param url
	 *            需要判断的url
	 * @return
	 */
	public static boolean getContentUrl(String url) {
		Pattern p = Pattern.compile("/usertmp/+[a-zA-Z0-9]+/",
				Pattern.CASE_INSENSITIVE);
		Matcher matcher = p.matcher(url);
		return matcher.find();
	}
}
